#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <cv.h>
#include <highgui.h>
#include <QtGui>
#include <stdio.h>
#include <string>
#include <sstream>
#include "Quadtree.h"
using namespace std;


IplImage *imagen= 0,*imagenFrame = 0, *sourceImage=0, *destinyImage=0, *tempImage=0 ;
IplImage *array [100] ;
IplConvKernel *myKernel = 0;
int indice = 0;
IplImage *imagenExteriorDia = 0,*imagenFramePrewitt = 0, *imagenDestino=0;
IplImage *filtradas[8];
MainWindow::MainWindow(QWidget *parent):QMainWindow(parent),ui(new Ui::MainWindow){
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::hitOrMiss(IplImage *src, IplImage *dst, IplImage* kernel)
{
    cvThreshold(src, src, 128, 255, CV_THRESH_BINARY);
    cvThreshold(kernel, kernel, 128, 255, CV_THRESH_BINARY);
    IplImage *k1 = cvCreateImage(cvSize(kernel->width, kernel->height), 8, 1);
    IplImage *k2 = cvCreateImage(cvSize(kernel->width, kernel->height), 8, 1);
    cvThreshold(kernel, k1, 128, 255, CV_THRESH_BINARY);
    //obtener el negativo de la matriz:
    cvSubRS(k1 , cvScalar(255) , k2);

       cvShowImage("kernel", kernel);
    cvShowImage("k1", k1);

    cvShowImage("k2", k2);

    IplConvKernel *e1, *e2;
    e1 = cvCreateStructuringElementEx(kernel->height, kernel->width, kernel->height-1,kernel->width-1, CV_SHAPE_RECT, IplImageToInt(k1));
    e2 = cvCreateStructuringElementEx(kernel->height, kernel->width,  kernel->height-1,kernel->width-1, CV_SHAPE_RECT, IplImageToInt(k2));


    IplImage *imgk1, *imgk2;
    imgk1 = cvCreateImage(cvSize(400,300), 8, 1);
    imgk2 = cvCreateImage(cvSize(400,300), 8, 1);

    cvErode(src,imgk1,e1,1);

    cvShowImage("Imgk1", imgk1);
    //complemento de src:
    cvSubRS(src , cvScalar(255) , src);
    cvErode(src,imgk2,e2,1);


    cvShowImage("Imgk2", imgk2);

    IplImage * dest = cvCreateImage(cvSize(400,300), 8, 1);

    cvAnd(imgk1,imgk2,dest,NULL);
    cvShowImage("hitormiss", dest);
    dst=dest;
}

int* MainWindow::cvMatToInt(CvMat *src)
{
    int converter[src->rows * src->cols];
    int counter=0;
    for(int i=0;i<src->rows;i++)
    {
        for(int j=0;j<src->cols;j++)
        {
           int element = CV_MAT_ELEM( *src,int, i, j );
            converter[counter]=element;
            counter++;
        }
    }
   return converter;
}

int* MainWindow::IplImageToInt(IplImage *src)
{
    int converter[src->height * src->width];
    int counter=0;
    for(int i=0;i<src->height;i++)
    {
        for(int j=0;j<src->width;j++)
        {

           uchar b = src->imageData[src->widthStep *i + j ];
           converter[counter]  = b;
            counter++;
        }
    }
   return converter;
}






/**
 * @brief MainWindow::skeleton
 * @param source
 * @param destiny
 * @param kernel
 * @param x
 * @param y
 *
 * Funcion para crear el Esqueleto de una imagen.
 */
void MainWindow::skeleton(IplImage *source, IplImage *destiny, IplConvKernel* kernel, int x, int y){
    IplImage *tempSkeleton;
    IplImage *tempOpening;
    int i = 0; // indice del while
    int ia = 0; // indice para almacenar las imagenes en el array
    bool done; // variable de decisicion del while
    do{
        //printf("Erodes %d \n",i);
        tempImage = cvCreateImage(cvSize(x, y), 8, 1);
        tempSkeleton= cvCreateImage(cvSize(x, y), 8, 1);
        tempOpening = cvCreateImage(cvSize(x, y), 8, 1);
        cvErode(source, tempImage, kernel, i);
        array[ia]=tempImage;
        cvMorphologyEx(tempImage, tempOpening, NULL,kernel,CV_MOP_OPEN,1);
        array[ia+1]=tempOpening;
        cvSub(tempImage, tempOpening, tempSkeleton, NULL);
        array[ia+2]=tempSkeleton;
        i++;
        ia = ia+3;
        //printf("cvCount: %d\n", cvCountNonZero(tempImage));
        done = (cvCountNonZero(tempImage)>1);
    }while(done);

    cvShowImage("Erode", array[0]);
    cvMoveWindow( "Erode", 50, 50 );
    cvShowImage("Opening", array[1]);
    cvMoveWindow( "Opening", 50, 400);
    cvShowImage("Subtraction", array[2]);
    cvMoveWindow("Subtraction", 980, 50 );


    //Union de todos los Sk(A)
    tempImage= cvCreateImage(cvSize(x, y), 8, 1);
    //tempSkeleton= cvCreateImage(cvSize(x, y), 8, 1);
    destiny = array[2];
    int in =2;
    while (array[in]!= NULL && array[in+3]!= NULL  ){
        cvAdd(  destiny, array[in+3], tempImage,NULL);
        destiny= cvCreateImage(cvSize(x, y), 8, 1);
        destiny=tempImage;
        tempImage= cvCreateImage(cvSize(x, y), 8, 1);
        in = in +3;
    }
    //destiny = tempSkeleton;
    cvShowImage("Esqueleto", destiny);
    cvMoveWindow("Esqueleto", 980, 400 );
    cvReleaseImage(&tempImage);
    cvReleaseImage(&tempOpening);
    cvReleaseImage(&tempSkeleton);
}

//ALGORITMO DE PREWITT
void MainWindow:: prewittFilter(IplImage *source, IplImage *destiny)
{
    //MASCARAS O KERNEL DEL FILTRO
    IplImage *tempimage = cvCreateImage(cvSize(400, 300), 8, 1);
    CvMat* n = cvCreateMat( 3, 3, CV_32FC1 );
    float element = -1;
    *( (float*)CV_MAT_ELEM_PTR( *n, 0, 0) ) = element;
    element= -1;
    *( (float*)CV_MAT_ELEM_PTR( *n, 0, 1 ) ) = element;
    element = -1;
    *( (float*)CV_MAT_ELEM_PTR( *n, 0, 2 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *n, 1, 0 ) ) = element;
    element = -2;
    *( (float*)CV_MAT_ELEM_PTR( *n, 1, 1 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *n, 1, 2 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *n, 2, 0 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *n, 2, 1 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *n, 2, 2 ) ) = element;
    cvFilter2D(source, tempimage, n, cvPoint(1,1));
    filtradas[0]=tempimage;

    tempimage = cvCreateImage(cvSize(400, 300), 8, 1);
    CvMat* s = cvCreateMat( 3, 3, CV_32FC1 );
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *s, 0, 0) ) = element;
    element= 1;
    *( (float*)CV_MAT_ELEM_PTR( *s, 0, 1 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *s, 0, 2 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *s, 1, 0 ) ) = element;
    element = -2;
    *( (float*)CV_MAT_ELEM_PTR( *s, 1, 1 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *s, 1, 2 ) ) = element;
    element = -1;
    *( (float*)CV_MAT_ELEM_PTR( *s, 2, 0 ) ) = element;
    element = -1;
    *( (float*)CV_MAT_ELEM_PTR( *s, 2, 1 ) ) = element;
    element = -1;
    *( (float*)CV_MAT_ELEM_PTR( *s, 2, 2 ) ) = element;
    cvFilter2D(source, tempimage, s, cvPoint(1,1));
    filtradas[1]=tempimage;

    tempimage = cvCreateImage(cvSize(400, 300), 8, 1);
    CvMat* e = cvCreateMat( 3, 3, CV_32FC1 );
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *e, 0, 0) ) = element;
    element= 1;
    *( (float*)CV_MAT_ELEM_PTR( *e, 0, 1 ) ) = element;
    element = -1;
    *( (float*)CV_MAT_ELEM_PTR( *e, 0, 2 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *e, 1, 0 ) ) = element;
    element = -2;
    *( (float*)CV_MAT_ELEM_PTR( *e, 1, 1 ) ) = element;
    element = -1;
    *( (float*)CV_MAT_ELEM_PTR( *e, 1, 2 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *e, 2, 0 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *e, 2, 1 ) ) = element;
    element = -1;
    *( (float*)CV_MAT_ELEM_PTR( *e, 2, 2 ) ) = element;
    cvFilter2D(source, tempimage, e, cvPoint(1,1));
    filtradas[2]=tempimage;

    tempimage = cvCreateImage(cvSize(400, 300), 8, 1);
    CvMat* o = cvCreateMat( 3, 3, CV_32FC1 );
    element = -1;
    *( (float*)CV_MAT_ELEM_PTR( *o, 0, 0) ) = element;
    element= 1;
    *( (float*)CV_MAT_ELEM_PTR( *o, 0, 1 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *o, 0, 2 ) ) = element;
    element = -1;
    *( (float*)CV_MAT_ELEM_PTR( *o, 1, 0 ) ) = element;
    element = -2;
    *( (float*)CV_MAT_ELEM_PTR( *o, 1, 1 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *o, 1, 2 ) ) = element;
    element = -1;
    *( (float*)CV_MAT_ELEM_PTR( *o, 2, 0 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *o, 2, 1 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *o, 2, 2 ) ) = element;
    cvFilter2D(source, tempimage, o, cvPoint(1,1));
    filtradas[3]=tempimage;

    tempimage = cvCreateImage(cvSize(400, 300), 8, 1);
    CvMat* so = cvCreateMat( 3, 3, CV_32FC1 );
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *so, 0, 0) ) = element;
    element= 1;
    *( (float*)CV_MAT_ELEM_PTR( *so, 0, 1 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *so, 0, 2 ) ) = element;
    element = -1;
    *( (float*)CV_MAT_ELEM_PTR( *so, 1, 0 ) ) = element;
    element = -2;
    *( (float*)CV_MAT_ELEM_PTR( *so, 1, 1 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *so, 1, 2 ) ) = element;
    element = -1;
    *( (float*)CV_MAT_ELEM_PTR( *so, 2, 0 ) ) = element;
    element = -1;
    *( (float*)CV_MAT_ELEM_PTR( *so, 2, 1 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *so, 2, 2 ) ) = element;
    cvFilter2D(source, tempimage, so, cvPoint(1,1));
    filtradas[4]=tempimage;

    tempimage = cvCreateImage(cvSize(400, 300), 8, 1);
    CvMat* no = cvCreateMat( 3, 3, CV_32FC1 );
    element = -1;
    *( (float*)CV_MAT_ELEM_PTR( *no, 0, 0) ) = element;
    element= -1;
    *( (float*)CV_MAT_ELEM_PTR( *no, 0, 1 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *no, 0, 2 ) ) = element;
    element = -1;
    *( (float*)CV_MAT_ELEM_PTR( *no, 1, 0 ) ) = element;
    element = -2;
    *( (float*)CV_MAT_ELEM_PTR( *no, 1, 1 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *no, 1, 2 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *no, 2, 0 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *no, 2, 1 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *no, 2, 2 ) ) = element;
    cvFilter2D(source, tempimage, no, cvPoint(1,1));
    filtradas[5]=tempimage;

    tempimage = cvCreateImage(cvSize(400, 300), 8, 1);
    CvMat* se = cvCreateMat( 3, 3, CV_32FC1 );
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *se, 0, 0) ) = element;
    element= 1;
    *( (float*)CV_MAT_ELEM_PTR( *se, 0, 1 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *se, 0, 2 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *se, 1, 0 ) ) = element;
    element = -2;
    *( (float*)CV_MAT_ELEM_PTR( *se, 1, 1 ) ) = element;
    element = -1;
    *( (float*)CV_MAT_ELEM_PTR( *se, 1, 2 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *se, 2, 0 ) ) = element;
    element = -1;
    *( (float*)CV_MAT_ELEM_PTR( *se, 2, 1 ) ) = element;
    element = -1;
    *( (float*)CV_MAT_ELEM_PTR( *se, 2, 2 ) ) = element;
    cvFilter2D(source, tempimage, se, cvPoint(1,1));
    filtradas[6]=tempimage;

    tempimage = cvCreateImage(cvSize(400, 300), 8, 1);
    CvMat* ne = cvCreateMat( 3, 3, CV_32FC1 );
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *ne, 0, 0) ) = element;
    element= -1;
    *( (float*)CV_MAT_ELEM_PTR( *ne, 0, 1 ) ) = element;
    element = -1;
    *( (float*)CV_MAT_ELEM_PTR( *ne, 0, 2 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *ne, 1, 0 ) ) = element;
    element = -2;
    *( (float*)CV_MAT_ELEM_PTR( *ne, 1, 1 ) ) = element;
    element = -1;
    *( (float*)CV_MAT_ELEM_PTR( *ne, 1, 2 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *ne, 2, 0 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *ne, 2, 1 ) ) = element;
    element = 1;
    *( (float*)CV_MAT_ELEM_PTR( *ne, 2, 2 ) ) = element;
    cvFilter2D(source, tempimage, ne, cvPoint(1,1));
    filtradas[7]=tempimage;

    //SUMA DE LAS IMAGENES FILTRADAS QUE SE ENCUENTRAN EN filtradas[]

    tempimage = cvCreateImage(cvSize(400, 300), 8, 1);
    tempimage = filtradas[0];
    IplImage *tempdst= cvCreateImage(cvSize(400, 300), 8, 1);
    for (int i = 0; i<7;i++){
        cvAdd(  tempimage , filtradas[i+1], tempdst,NULL);
        tempimage=tempdst;
        tempdst= cvCreateImage(cvSize(400, 300), 8, 1);
    }
    cvShowImage("Filtro Prewitt", tempimage);
    //destiny= tempimage;
}

void MainWindow::on_button_Adelgazamiento_clicked()
{
    imagen= cvLoadImage("../taller 3.1 TIA/img.jpg",0); // cambiar la ruta de la imagen
    imagenFrame = cvCreateImage(cvSize(400, 300), 8, 1);
    cvResize(imagen, imagenFrame, CV_INTER_LINEAR);

    CvMat *mat = cvCreateMat(imagenFrame->height,imagenFrame->width,CV_8UC1 );
    cvConvert( imagenFrame, mat );

        cvShowImage("Imagen", mat);
    MorphologicalThinning(mat,mat);
    cvShowImage("Imagen1", mat);

}

void MainWindow::on_button_Esqueleto_clicked()
{
    ui->button_Next->setEnabled(true);
    ui->button_Previous->setEnabled(true);
    ui->button_CerrarEsqueleto->setEnabled(true);

    int tempArray [9]={1,1,1,1,1,1,1,1,1};
    myKernel = cvCreateStructuringElementEx(3,3,1,1, CV_SHAPE_RECT,tempArray);
    sourceImage= cvLoadImage("../taller 3.1 TIA/Test3.jpg",0);
    tempImage = cvCreateImage(cvSize(300, 300), 8, 1);
    cvResize(sourceImage, tempImage, CV_INTER_LINEAR);
    sourceImage=tempImage;
    cvThreshold(sourceImage, sourceImage, 128, 255, CV_THRESH_BINARY);
    destinyImage = cvCreateImage(cvSize(300,300),8,1);
    cvShowImage("Imagen Fuente", sourceImage);
    cvMoveWindow("Imagen Fuente", 510, 410 );
    skeleton(sourceImage, destinyImage, myKernel, 300, 300);
}

void MainWindow::on_button_Previous_clicked()
{
    if (indice >= 3){
        indice = indice -3;
        cvShowImage("Erode", array[indice]);
        cvShowImage("Opening", array[indice+1]);
        cvShowImage("Subtraction", array[indice+2]);
    }
}

void MainWindow::on_button_Next_clicked()
{
    if (indice <= 30){
        indice = indice +3;
        cvShowImage("Erode", array[indice]);
        cvShowImage("Opening", array[indice+1]);
        cvShowImage("Subtraction", array[indice+2]);
    }
}

void MainWindow::on_button_CerrarEsqueleto_clicked()
{
    cvDestroyWindow("Erode");
    cvDestroyWindow("Opening");
    cvDestroyWindow("Subtraction");
    cvDestroyWindow("Imagen Fuente");
    cvDestroyWindow("Esqueleto");
    ui->button_CerrarEsqueleto->setEnabled(false);
}

void MainWindow::on_prewittButton_clicked()
{
    imagenExteriorDia= cvLoadImage("../taller 3.1 TIA/exteriorDia.JPG",0); // cambiar la ruta de la imganen
    imagenFramePrewitt = cvCreateImage(cvSize(400, 300), 8, 1);
    imagenDestino = cvCreateImage(cvSize(400, 300), 8, 1);
    cvResize(imagenExteriorDia, imagenFramePrewitt, CV_INTER_LINEAR);
    imagenExteriorDia=imagenFramePrewitt;

    prewittFilter(imagenExteriorDia,imagenDestino);
}




void MainWindow::MorphologicalThinning(CvMat *pSrc, CvMat *pDst) {
        bool bDone = false;
        int rows = pSrc->rows;
        int cols = pSrc->cols;
        /// pad source
        CvMat *p_enlarged_src = cvCreateMat(rows + 2, cols + 2, CV_32FC1);
        for(int i = 0; i < (rows+2); i++) {
                CV_MAT_ELEM(*p_enlarged_src, float, i, 0)	 = 0.0f;
                CV_MAT_ELEM(*p_enlarged_src, float, i, cols+1)	= 0.0f;
        }
        for(int j = 0; j < (cols+2); j++) {
                CV_MAT_ELEM(*p_enlarged_src, float, 0, j)	 = 0.0f;
                CV_MAT_ELEM(*p_enlarged_src, float, rows+1, j)	= 0.0f;
        }
        for(int i = 0; i < rows; i++) {
                for(int j = 0; j < cols; j++) {
                        if (CV_MAT_ELEM(*pSrc, float, i, j) >= 0.5f) {
                                CV_MAT_ELEM(*p_enlarged_src, float, i+1, j+1) = 1.0f;
                        }
                        else
                                CV_MAT_ELEM(*p_enlarged_src, float, i+1, j+1) = 0.0f;
                }
        }
        /// start to thin
        CvMat *p_thinMat1	= cvCreateMat(rows + 2, cols + 2, CV_32FC1);
        CvMat *p_thinMat2	= cvCreateMat(rows + 2, cols + 2, CV_32FC1);
        CvMat *p_cmp	 = cvCreateMat(rows + 2, cols + 2, CV_8UC1);
        while (bDone != true) {
                /// sub-iteration 1
                ThinSubiteration1(p_enlarged_src, p_thinMat1);
                /// sub-iteration 2
                ThinSubiteration2(p_thinMat1, p_thinMat2);
                /// compare
                cvCmp(p_enlarged_src, p_thinMat2, p_cmp, CV_CMP_EQ);
                /// check
                int num_non_zero = cvCountNonZero(p_cmp);
                if(num_non_zero == (rows + 2) * (cols + 2)) {
                        bDone = true;
                }
                /// copy
                cvCopy(p_thinMat2, p_enlarged_src);
        }
        /// copy result
        for(int i = 0; i < rows; i++) {
                for(int j = 0; j < cols; j++) {
                        CV_MAT_ELEM(*pDst, float, i, j) = CV_MAT_ELEM(*p_enlarged_src, float, i+1, j+1);
                }
        }
        /// clean memory
        cvReleaseMat(&p_enlarged_src);
        cvReleaseMat(&p_thinMat1);
        cvReleaseMat(&p_thinMat2);
        cvReleaseMat(&p_cmp);
}
void MainWindow:: ThinSubiteration1(CvMat *pSrc, CvMat *pDst) {
        int rows = pSrc->rows;
        int cols = pSrc->cols;
        cvCopy(pSrc, pDst);
        for(int i = 0; i < rows; i++) {
                for(int j = 0; j < cols; j++) {
                        if(CV_MAT_ELEM(*pSrc, float, i, j) == 1.0f) {
                                /// get 8 neighbors
                                /// calculate C(p)
                                int neighbor0 = (int) CV_MAT_ELEM(*pSrc, float, i-1, j-1);
                                int neighbor1 = (int) CV_MAT_ELEM(*pSrc, float, i-1, j);
                                int neighbor2 = (int) CV_MAT_ELEM(*pSrc, float, i-1, j+1);
                                int neighbor3 = (int) CV_MAT_ELEM(*pSrc, float, i, j+1);
                                int neighbor4 = (int) CV_MAT_ELEM(*pSrc, float, i+1, j+1);
                                int neighbor5 = (int) CV_MAT_ELEM(*pSrc, float, i+1, j);
                                int neighbor6 = (int) CV_MAT_ELEM(*pSrc, float, i+1, j-1);
                                int neighbor7 = (int) CV_MAT_ELEM(*pSrc, float, i, j-1);
                                int C = int(~neighbor1 & ( neighbor2 | neighbor3)) +
                                                 int(~neighbor3 & ( neighbor4 | neighbor5)) +
                                                 int(~neighbor5 & ( neighbor6 | neighbor7)) +
                                                 int(~neighbor7 & ( neighbor0 | neighbor1));
                                if(C == 1) {
                                        /// calculate N
                                        int N1 = int(neighbor0 | neighbor1) +
                                                         int(neighbor2 | neighbor3) +
                                                         int(neighbor4 | neighbor5) +
                                                         int(neighbor6 | neighbor7);
                                        int N2 = int(neighbor1 | neighbor2) +
                                                         int(neighbor3 | neighbor4) +
                                                         int(neighbor5 | neighbor6) +
                                                         int(neighbor7 | neighbor0);
                                        int N = min(N1,N2);
                                        if ((N == 2) || (N == 3)) {
                                                /// calculate criteria 3
                                                int c3 = ( neighbor1 | neighbor2 | ~neighbor4) & neighbor3;
                                                if(c3 == 0) {
                                                        CV_MAT_ELEM(*pDst, float, i, j) = 0.0f;
                                                }
                                        }
                                }
                        }
                }
        }
}


void MainWindow::ThinSubiteration2(CvMat *pSrc, CvMat *pDst) {
        int rows = pSrc->rows;
        int cols = pSrc->cols;
        cvCopy(pSrc, pDst);
        for(int i = 0; i < rows; i++) {
                for(int j = 0; j < cols; j++) {
                        if ( CV_MAT_ELEM(*pSrc, float, i, j) == 1.0f) {
                                /// get 8 neighbors
                                /// calculate C(p)
                                int neighbor0 = (int) CV_MAT_ELEM(*pSrc, float, i-1, j-1);
                                int neighbor1 = (int) CV_MAT_ELEM(*pSrc, float, i-1, j);
                                int neighbor2 = (int) CV_MAT_ELEM(*pSrc, float, i-1, j+1);
                                int neighbor3 = (int) CV_MAT_ELEM(*pSrc, float, i, j+1);
                                int neighbor4 = (int) CV_MAT_ELEM(*pSrc, float, i+1, j+1);
                                int neighbor5 = (int) CV_MAT_ELEM(*pSrc, float, i+1, j);
                                int neighbor6 = (int) CV_MAT_ELEM(*pSrc, float, i+1, j-1);
                                int neighbor7 = (int) CV_MAT_ELEM(*pSrc, float, i, j-1);
                                int C = int(~neighbor1 & ( neighbor2 | neighbor3)) +
                                        int(~neighbor3 & ( neighbor4 | neighbor5)) +
                                        int(~neighbor5 & ( neighbor6 | neighbor7)) +
                                        int(~neighbor7 & ( neighbor0 | neighbor1));
                                if(C == 1) {
                                        /// calculate N
                                        int N1 = int(neighbor0 | neighbor1) +
                                                int(neighbor2 | neighbor3) +
                                                int(neighbor4 | neighbor5) +
                                                int(neighbor6 | neighbor7);
                                        int N2 = int(neighbor1 | neighbor2) +
                                                int(neighbor3 | neighbor4) +
                                                int(neighbor5 | neighbor6) +
                                                int(neighbor7 | neighbor0);
                                        int N = min(N1,N2);
                                        if((N == 2) || (N == 3)) {
                                                int E = (neighbor5 | neighbor6 | ~neighbor0) & neighbor7;
                                                if(E == 0) {
                                                        CV_MAT_ELEM(*pDst, float, i, j) = 0.0f;
                                                }
                                        }
                                }
                        }
                }
        }
}





void MainWindow::on_splitAndMergeButton_clicked()
{
   IplImage *sourceImage= cvLoadImage("../taller 3.1 TIA/Test3.jpg",0);
   IplImage *imagenFrameSeg = cvCreateImage(cvSize(400, 300), 8, 1);
   cvResize(sourceImage, imagenFrameSeg, CV_INTER_LINEAR);
   sourceImage = imagenFrameSeg;

   splitAndMergeSegmentation(sourceImage,sourceImage);
}
void MainWindow:: splitAndMergeSegmentation(IplImage *source, IplImage *destiny)
{
    cvThreshold(source, source, 128, 255, CV_THRESH_BINARY);
    cvShowImage("splitandmerge",source);
     Quadtree *n= new Quadtree(0,0,source->width,source->height,0,2);
     llenarQuadtree(source,n,0);


     vector<Object*> objs= n->objects;
     for(int i=0;i<objs.size();i++)
     {
        IplImage *curr=objs[i]->image;
        char c= (rand() % 100);
        cvShowImage(&c,curr);
     }

    CvRect roi;
    roi = cvRect(20,20,40,50);//this is the rectangle you want to split for example
    cvSetImageROI(source,roi);
    //here you create an image with the dimensions of the rectangle
    IplImage *image_to_split = cvCreateImage( cvSize(source->roi->width,source->roi->height),
    8, 1);
    //here you split the image of the rectangle into image_to_split
    cvCopy(source,image_to_split);
      //do what you want with the image_to_split

      // and here you will merge the image in the source image
    cvCopy(image_to_split,source);
    cvResetImageROI(source);
    cvReleaseImage(&source);
    cvReleaseImage(&image_to_split);

}
void MainWindow:: llenarQuadtree(IplImage *source, Quadtree *arbol,int nivel)
{

    CvScalar stdDev,mean;
    cvAvgSdv(source,&mean,&stdDev);
    if(*stdDev.val>50 && nivel<=arbol->maxLevel)
    {
        printf("\nDesviacion estandar %f",*stdDev.val);
        printf("\n source.x: %d",source->width);
        printf("\n source.y: %d",source->height);

        //partir la imagen en nw , ne , sw, se:
        CvRect roi;
        roi = cvRect(arbol->x,arbol->y,source->width/2,source->height/2);//region de interes
        cvSetImageROI(source,roi);
        IplImage *NWImage = cvCreateImage( cvSize(source->roi->width,source->roi->height),
        8, 1);

        cvCopy(source,NWImage);

       // c = (rand() % 100);
        //cvShowImage(&c,NWImage);
        Object *NW= new Object(arbol->x,arbol->y,source->width/2,source->height/2,source);
        arbol->AddObject(NW);


        roi = cvRect(arbol->x+ source->width/2,arbol->y,source->width/2,source->height/2);//region de interes
        cvSetImageROI(source,roi);
        IplImage *NEImage = cvCreateImage( cvSize(source->roi->width,source->roi->height),
        8, 1);
        cvCopy(source,NEImage);


        // c = (rand() % 100);
        //cvShowImage(&c,NEImage);
        Object *NE= new Object(arbol->x+source->width/2,arbol->y,source->width/2,source->height/2,source);
        arbol->AddObject(NE);



        roi = cvRect(arbol->x,arbol->y+source->height/2,source->width/2,source->height/2);//region de interes
        cvSetImageROI(source,roi);
        IplImage *SWImage = cvCreateImage( cvSize(source->roi->width,source->roi->height),
        8, 1);
        cvCopy(source,SWImage);



        // c = (rand() % 100);
       // cvShowImage("&c",SWImage);
        Object *SW= new Object(arbol->x,arbol->y+source->height/2,source->width/2,source->height/2,source);
        arbol->AddObject(SW);


        roi = cvRect(arbol->x+source->width/2,arbol->y+source->height/2,source->width/2,source->height/2);//region de interes
        cvSetImageROI(source,roi);
        IplImage *SEImage = cvCreateImage( cvSize(source->roi->width,source->roi->height),
        8, 1);
        cvCopy(source,SEImage);



       // c = (rand() % 100);
     //   cvShowImage(&c,SEImage);
        Object *SE= new Object(arbol->x+source->width/2,arbol->y+source->height/2,source->width/2,source->height/2,source);
        arbol->AddObject(SE);


       llenarQuadtree(NWImage,arbol,nivel+1);
       llenarQuadtree(NEImage,arbol,nivel+1);
       llenarQuadtree(SWImage,arbol,nivel+1);
       llenarQuadtree(SEImage,arbol,nivel+1);

    }
}






